#region Header

// MS codename Velocity Distributed Cache Extensions.
// (c) 2009

#endregion


#region Usings

using System;

using Caching.Extension.Core.Tests.Utils;
using Caching.Extensions.Core;
using Caching.Extensions.Core.Impl;

using NUnit.Framework;

#endregion


namespace Caching.Extension.Core.Tests.Core
{
    [Category("Performance")]
    public abstract class SmartCachePerformanceTestBase : SmartCacheTestsBase
    {
        protected const int ItemSize = 48*1000;
        protected const int Iterations = 1*50;
        protected const int MaxItemCount = 100;
        private const string DefaultCache = "";


        #region Tests

        #endregion Tests


        protected static void FillCache(string keyPrefix, int maxIndex, Action<string, object> put)
        {
            for (int i = 0; i < maxIndex; i++)
            {
                string key = keyPrefix + i;
                put(key, CreateItem());
            }
        }


        protected void GetTest(string keyPrefix, Func<string, object> action)
        {
            Random rnd = new Random(DateTime.UtcNow.Second);
            for (int i = 0; i < Iterations; i++)
            {
                int idx = rnd.Next(MaxItemCount);
                string key = keyPrefix + idx;

                object item = action(key);
                Expect(item, Is.Not.Null, "key: " + key);
            }
        }


        protected static object CreateItem()
        {
            int[] array = new int[ItemSize];
            for (int i = 0; i < ItemSize; i++)
            {
                array[i] = i;
            }
            return array;
        }


        #region Test Setup

        internal override InprocessCache CreateLocalCache()
        {
            return new InprocessCache(TimeSpan.FromMinutes(5));
        }

        #endregion Test Setup


        protected void PutToMsCache(string cacheKey, object item)
        {
            MsCache.Put(cacheKey, item);
        }


        protected void PutToSmartCache(string cacheKey, object item)
        {
            TestCache.Put(cacheKey, item, TimeSpan.FromMinutes(10), DefaultCache);
        }


        protected object GetFromMsCache(string cacheKey)
        {
            return MsCache.Get(cacheKey);
        }


        protected object GetFromSmartCache(string cacheKey)
        {
            return TestCache.Get(cacheKey, null);
        }
    }


    [TestFixture]
    public class MsCachePerformanceTest : SmartCachePerformanceTestBase
    {
        #region Overrides of SmartCacheTestBase

        internal override ISmartCache CreateSmartCache()
        {
            return null;
        }

        #endregion


        protected override void PostSetUp()
        {
            base.PostSetUp();
            FillCache(Key, MaxItemCount, PutToMsCache);
        }


        [Test]
        public void Get()
        {
            GetTest(Key, GetFromMsCache);
        }
    }


    [TestFixture]
    public class SmartCachePerformanceWithQueryUpdate : SmartCachePerformanceTestBase
    {
        #region Overrides of SmartCacheTestBase

        internal override ISmartCache CreateSmartCache()
        {
            return new SmartCache("test", LocalCache, TimeSpan.FromMinutes(10), MsCache, true);
        }

        #endregion


        protected override void PostSetUp()
        {
            base.PostSetUp();
            FillCache(Key, MaxItemCount, PutToMsCache);
        }


        [Test]
        public void Test()
        {
            GetTest(Key, GetFromSmartCache);
        }
    }


    [TestFixture]
    public class SmartCachePerformanceTestWithoutQueryUpdate : SmartCachePerformanceTestBase
    {
        #region Overrides of SmartCacheTestBase

        internal override ISmartCache CreateSmartCache()
        {
            return new SmartCache("test", LocalCache, TimeSpan.FromMinutes(10), MsCache, false);
        }

        #endregion


        protected override void PostSetUp()
        {
            base.PostSetUp();
            FillCache(Key, MaxItemCount, PutToMsCache);
        }


        [Test]
        public void Test()
        {
            GetTest(Key, GetFromSmartCache);
        }
    }
}